package com.wmyg.antifake.config;

import com.wmyg.antifake.oauth.SysUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

/**
 * @program 前后端分离版妙码后台
 * @description password模式授权认证服务器配置
 * @author 王卓逸
 * @create 2019-04-15
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {

    /**
     * password模式所需对象
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisConnectionFactory connectionFactory;

    /**
     * 密码加密编码器
     */
    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    SysUserDetailService sysUserDetailService;

    /**
     * @return 本地内存存储token
     */
    @Bean
    public TokenStore memoryTokenStore() {
        return new RedisTokenStore(connectionFactory);
//        return new InMemoryTokenStore();
    }

    /**
     * 配置token存储方式等
     * @param endpoints 终端配置
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager)
                .tokenStore(memoryTokenStore())
                .userDetailsService(sysUserDetailService);
    }

    /**
     * 配置认证服务器拦截规则
     * @param oauthServer 认证服务器配置类
     * @throws Exception 可忽略
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(passwordEncoder)
                .allowFormAuthenticationForClients();
    }

    /**
     * 客户端配置
     * @param clients 客户端配置类
     * @throws Exception 可忽略
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("miaoManager")
                .secret(passwordEncoder.encode("Wmyg2019miaomark"))
                .authorizedGrantTypes("password")
                .scopes("all");
    }

}
